﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text.RegularExpressions;
using MediaController.Subs.Provider;

namespace MediaController.Subs
{
    public class SratimProvider : SubtitlesProvider
    {
        private const string SearchURL = "Http://www.sratim.co.il/browse.php?q=";
        private const string MoviePageURL = "http://www.sratim.co.il/view.php?id=";
        private const string SubtitlesPageURL = "http://www.sratim.co.il/subtitles.php?mid=";
        private const char Q = ControlChars.Quote;
        private const int Timeout = 200000;

        protected override TitleResult[] GetTitles(TitleFileInfo titleFileInfo)
        {
            HttpWebRequest request;
            HttpWebResponse response = null;
            StreamReader reader = null;
            try
            {
                request = (HttpWebRequest)WebRequest.Create(SearchURL + titleFileInfo.TitleName);
                request.Timeout = Timeout;
                response = (HttpWebResponse)request.GetResponse();
                reader = new StreamReader(response.GetResponseStream());
                string html = reader.ReadToEnd();

                TitleResult[] results = AnalyzeMovieResults(html);
                if (results == null || results.Length == 0 
                    && titleFileInfo.TitleFileInfoByFolderName != null)
                {
                    results = GetTitles(titleFileInfo.TitleFileInfoByFolderName);
                }
                return results;
            }
            catch (TimeoutException)
            {
                InvokeProgressChanged(new SubsProgressEventArgs(titleFileInfo, 0, " GetTitles Timeout"));
                return null;
            }
            catch (Exception)
            {
                return null;
            }
            finally
            {
                if (response != null) response.Close();
                if (reader != null)
                {
                    reader.Close();
                    reader.Dispose();
                }
            }
        }

        protected override SubtitleResult[] GetSubtitles(TitleFileInfo titleFileInfo, TitleResult movieResult)
        {
            try
            {
                if (titleFileInfo.IsSeries)
                {
                    return GetSubtitleResults(movieResult.Id, titleFileInfo.Season, titleFileInfo.Episode);
                }
                else
                {
                    return GetSubtitleResults(movieResult.Id);
                }
            }
            catch (TimeoutException)
            {
                InvokeProgressChanged(new SubsProgressEventArgs(titleFileInfo, 0, "GetSubtitles Timeout"));
                return null;
            }
            catch (Exception)
            {
                return null;
            }
        }

        private TitleResult[] AnalyzeMovieResults(string html)
        {
            Match name;
            Match year = null;
            Match isSeries;
            Match id;
            var titleResults = new List<TitleResult>();

            Match movieResult = Regex.Match(html, "<a href=.view.php.+?קהילה", RegexOptions.Singleline);

            while (movieResult.Success)
            {
                isSeries = Regex.Match(movieResult.Value, "סדרה:", RegexOptions.Singleline);
                if (isSeries.Success)
                {
                    name = Regex.Match(movieResult.Value, "(?<=סדרה:).+?(?=\\||" + Q + ")", RegexOptions.Singleline);
                }
                else
                {
                    name = Regex.Match(movieResult.Value, "(?<=סרט:).+?(?=\\||" + Q + ")", RegexOptions.Singleline);
                    year = Regex.Match(movieResult.Value, "(?<=<span class=.smtext.>)\\d\\d\\d\\d(?=</span>)", RegexOptions.Singleline);
                }
                id = Regex.Match(movieResult.Value, "(?<=id=)\\d+(?=" + Q + ")", RegexOptions.Singleline);

                var titleResult = new TitleResult();
                titleResult.Name = name.Value.Trim();
                titleResult.IsSeries = isSeries.Success;
                titleResult.Id = id.Value.Trim();
                titleResult.Year = !isSeries.Success ? year.Value.Trim() : "";

                titleResults.Add(titleResult);

                movieResult = movieResult.NextMatch();
            }

            return titleResults.ToArray();
        }

        private SubtitleResult[] GetSubtitleResults(string titleId)
        {
            if (titleId == null) throw new ArgumentNullException("titleId");
            HttpWebRequest request;
            HttpWebResponse response = null;
            StreamReader reader = null;

            try
            {
                request = (HttpWebRequest)WebRequest.Create(SubtitlesPageURL + titleId.Substring(1));
                request.Timeout = Timeout;
                request.AllowAutoRedirect = false;
                response = (HttpWebResponse)request.GetResponse();
                reader = new StreamReader(response.GetResponseStream());
                string html = reader.ReadToEnd();

                SubtitleResult[] results = AnalyzeSubtitleResults(html);
                return results;
            }
            finally
            {
                if (response != null) response.Close();
                if (reader != null)
                {
                    reader.Close();
                    reader.Dispose();
                }
            }
        }

        private SubtitleResult[] GetSubtitleResults(string titleId, string season, string episode)
        {
            HttpWebRequest request;
            HttpWebResponse response = null;
            StreamReader reader = null;
            Match seasonId;
            Match episodeId;

            try
            {
                request = (HttpWebRequest)WebRequest.Create(MoviePageURL + titleId);
                request.Timeout = Timeout;
                request.AllowAutoRedirect = false;
                response = (HttpWebResponse)request.GetResponse();
                reader = new StreamReader(response.GetResponseStream());
                string html = reader.ReadToEnd();
                response.Close();
                reader.Close();
                reader.Dispose();
                seasonId = Regex.Match(html, "(?<=id=)\\d+(?=. class=.smtext.>עונה " + Convert.ToInt32(season) + ")");

                request = (HttpWebRequest)WebRequest.Create(MoviePageURL + seasonId.Value);
                response = (HttpWebResponse)request.GetResponse();
                reader = new StreamReader(response.GetResponseStream());
                html = reader.ReadToEnd();
                response.Close();
                reader.Close();
                reader.Dispose();
                episodeId = Regex.Match(html, "(?<=id=)\\d+(?=.><b>פרק " + Convert.ToInt32(episode) + ")");

                request = (HttpWebRequest)WebRequest.Create(SubtitlesPageURL + episodeId.Value.Substring(1));
                request.Timeout = Timeout;
                response = (HttpWebResponse)request.GetResponse();
                reader = new StreamReader(response.GetResponseStream());
                html = reader.ReadToEnd();
                response.Close();
                reader.Close();
                reader.Dispose();
                SubtitleResult[] results = AnalyzeSubtitleResults(html);
                return results;
            }
            finally
            {
                if (response != null) response.Close();
                if (reader != null)
                {
                    reader.Close();
                    reader.Dispose();
                }
            }
        }

        private SubtitleResult[] AnalyzeSubtitleResults(string html)
        {
            var subtitleResults = new List<SubtitleResult>();
            var subtitleResult = Regex.Match(html, "subtitle_tab.+?</table>", RegexOptions.Singleline);

            while (subtitleResult.Success)
            {
                var name = Regex.Match(subtitleResult.Value, "(?<=subtitle_title.+?title=.).+?(?=" + Q + ")");
                var language = Regex.Match(subtitleResult.Value, "images/Flags/1.png");
                var cdCount = Regex.Match(subtitleResult.Value, "(?<=images/cds/cd)\\d");
                var link = Regex.Match(subtitleResult.Value, "downloadsubtitle.php\\?id=\\d+");

                if (language.Success)
                {
                    var subResult = new SubtitleResult();
                    subResult.Name = name.Value.Trim();
                    subResult.CDCount = cdCount.Value.Trim();
                    subResult.Link = "Http://www.sratim.co.il/" + link.Value.Trim();
                    subtitleResults.Add(subResult);

                }
                subtitleResult = subtitleResult.NextMatch();
            }

            return subtitleResults.ToArray();
        }
    }
}